﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Windows.Forms;
using Assist;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Events;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Selection;
using YArchitech.Controls;
using YArchitech.ProgressBar;
using YArchitech.Revit;
using YJKArch.Utils;
using HYOpeningCommon.DataEnum;
using HYOpeningCommon.DbOpening;
using HYOpeningCommon.Public;
using HYOpeningCreate.ConfigForm;

namespace HYOpeningCreate.Cmd
{
	[Transaction(TransactionMode.Manual)]
	[Regeneration(RegenerationOption.Manual)]
	public class CmdOpeningCreate : IExternalCommand
	{
		public Result Execute(ExternalCommandData cmdData, ref string messages, ElementSet elements)
		{
			UIDocument activeUIDocument = cmdData.Application.ActiveUIDocument;
			this.m_doc = activeUIDocument.Document;
			this.m_cmdData = cmdData;
			cmdData.Application.Application.FailuresProcessing += this.OnFailuresProcessing;
			try
			{
				if (cmdData.Application.ActiveUIDocument.Document.IsModified)
				{
					MessageBox.Show("请先保存项目。");
					return Autodesk.Revit.UI.Result.Cancelled;
				}
				List<Level> sortLevels = Common.GetSortLevels(this.m_doc, double.MinValue, double.MaxValue);
				if (sortLevels != null)
				{
					DbOpeningBase.m_lstLevel = sortLevels;
				}
				if (CmdOpeningCreate.m_HWndRevit == null)
				{
					CmdOpeningCreate.m_HWndRevit = new WindowHandle(Process.GetCurrentProcess().MainWindowHandle);
				}
				SelecteXmlPathForm selecteXmlPathForm = new SelecteXmlPathForm(ESelecteXmlPathForm.eCreateOpening);
				if (selecteXmlPathForm.ShowDialog() != DialogResult.OK)
				{
					return Autodesk.Revit.UI.Result.Cancelled;
				}
				this.m_OpeningImpExpManager = new DbOpeningImpExpManager(selecteXmlPathForm.XmlPathName);
				this.m_LstDbOpeningBase = this.m_OpeningImpExpManager.ImportOpeningByXml();
				this.GetCategoryOpeningLst();
				if (!this.CreatePreviewInstancesAndShowReport(activeUIDocument))
				{
					return Autodesk.Revit.UI.Result.Cancelled;
				}
			}
			catch
			{
			}
			return Autodesk.Revit.UI.Result.Succeeded;
		}

		public void OnFailuresProcessing(object sender, FailuresProcessingEventArgs e)
		{
			FailuresAccessor failuresAccessor = e.GetFailuresAccessor();
			string transactionName = failuresAccessor.GetTransactionName();
			IList<FailureMessageAccessor> failureMessages = failuresAccessor.GetFailureMessages();
			if (failureMessages.Count == 0)
			{
				e.SetProcessingResult((FailureProcessingResult)0);
				return;
			}
			if (transactionName.Equals("RotateElement"))
			{
				foreach (FailureMessageAccessor failureMessageAccessor in failureMessages)
				{
					if ((int)failureMessageAccessor.GetSeverity() == 2)
					{
						failuresAccessor.ResolveFailure(failureMessageAccessor);
					}
					else if ((int)failureMessageAccessor.GetSeverity() == 1)
					{
						failuresAccessor.DeleteWarning(failureMessageAccessor);
					}
				}
				e.SetProcessingResult((FailureProcessingResult)1);
				return;
			}
			if (transactionName.Equals("CreateOpeningFamilyInstance"))
			{
				foreach (FailureMessageAccessor failureMessageAccessor2 in failureMessages)
				{
					if ((int)failureMessageAccessor2.GetSeverity() == 2)
					{
						failuresAccessor.ResolveFailure(failureMessageAccessor2);
					}
					else if ((int)failureMessageAccessor2.GetSeverity() == 1)
					{
						failuresAccessor.DeleteWarning(failureMessageAccessor2);
					}
				}
				e.SetProcessingResult((FailureProcessingResult)1);
				return;
			}
			e.SetProcessingResult((FailureProcessingResult)0);
		}

		private bool Create3DOpening(LinkedList<DbOpeningBase> lstNeedOpening)
		{
			LinkedList<Element> linkedList = new LinkedList<Element>();
			ProgressBarForm progressBarForm = new ProgressBarForm(lstNeedOpening.Count, ProgressBarStyle.Blocks, true);
			progressBarForm.Text = "正在开洞...";
			progressBarForm.ShowInTaskbar = false;
			progressBarForm.Show(CmdOpeningCreate.m_HWndRevit);
			ViewScene viewScene = new ViewScene();
			viewScene.m_viewOpening2D = this.m_doc.ActiveView;
			using (TransactionGroup transactionGroup = new TransactionGroup(this.m_doc))
			{
				transactionGroup.Start("TransGroupCreate3DOpening");
				try
				{
					string createOpeningDate = DateTime.Now.ToString();
					foreach (DbOpeningBase dbOpeningBase in lstNeedOpening)
					{
						dbOpeningBase.SetCreateOpeningDate(createOpeningDate);
						Element element;
						Element element2;
						if (!dbOpeningBase.CreateOpeningFamilyInstance(viewScene, out element, out element2))
						{
							string str = "剪切体GUID ：" + dbOpeningBase.m_strCutUniqueId;
							string str2 = "主体GUID ：" + dbOpeningBase.m_strHostUniqueId;
							transactionGroup.RollBack();
							progressBarForm.Dispose();
							ExceptionLog.WriteLog("开洞功能，剪切体GUID：" + str + " ，主体GUID：" + str2, false);
							ExceptionLog.CloseLogFile();
							return false;
						}
						if (element.IsValidObject)
						{
							dbOpeningBase.m_eOpeningState = EOpeningState.eOpen;
							dbOpeningBase.m_strGuid = element.UniqueId;
							dbOpeningBase.AddSharedParameters(element);
							if (!(dbOpeningBase is DbNativeOpening))
							{
								linkedList.AddLast(element);
							}
						}
						progressBarForm.RefreshProgressBar();
						if (progressBarForm.m_stopTag)
						{
							transactionGroup.RollBack();
							progressBarForm.Dispose();
							ExceptionLog.CloseLogFile();
							return false;
						}
					}
				}
				catch
				{
					transactionGroup.RollBack();
					progressBarForm.Dispose();
					ExceptionLog.CloseLogFile();
					return false;
				}
				Transaction transaction = new Transaction(this.m_doc, "修改非梁洞，使其显示出来");
				try
				{
					transaction.Start();
					foreach (Element element3 in linkedList)
					{
						if (element3 != null)
						{
							Parameter parameter = element3.GetParameter("立面");
							if (parameter != null)
							{
								parameter.Set(parameter.AsDouble() + 3.2808398950131235E-06);
							}
							else
							{
								parameter = element3.GetParameter("洞口高度");
								if (parameter != null)
								{
									parameter.Set(parameter.AsDouble() + 3.2808398950131235E-06);
								}
								else
								{
									parameter = element3.GetParameter("洞口直径");
									if (parameter != null)
									{
										parameter.Set(parameter.AsDouble() + 3.2808398950131235E-06);
									}
								}
							}
						}
					}
					transaction.Commit();
				}
				catch
				{
					transaction.RollBack();
					ExceptionLog.CloseLogFile();
					return false;
				}
				transactionGroup.Assimilate();
			}
			ExceptionLog.CloseLogFile();
			return true;
		}

		private bool CreatePreviewInstancesAndShowReport(UIDocument uiDoc)
		{
			new ViewScene().m_viewOpening2D = this.m_doc.ActiveView;
			Autodesk.Revit.DB.View activeView = uiDoc.ActiveView;
			CommonInterface.SetView3DChanged(uiDoc);
			bool result;
			using (TransactionGroup transactionGroup = new TransactionGroup(this.m_doc))
			{
				transactionGroup.Start("TransGroupCreateModelGroup");
				try
				{
					if (!this.CreateOpeningPreviewInstances())
					{
						transactionGroup.RollBack();
						YJKMessageBox.Show("创建预览过程中出现错误，命令结束！");
						return false;
					}
				}
				catch
				{
					transactionGroup.RollBack();
					YJKMessageBox.Show("创建预览过程中出现错误，命令结束！");
					return false;
				}
				try
				{
					OpeningCreateReportForm openingCreateReportForm = new OpeningCreateReportForm(uiDoc, CmdOpeningCreate.m_HWndRevit);
					openingCreateReportForm.TranslateOpeningDataToForm(this.m_lstNoWoringStruOpening, this.m_lstNoWoringBldOpening, this.m_lstWoringStruOpening, this.m_lstWoringBldOpening);
					openingCreateReportForm.SetOpeningData2DataGridView();
					openingCreateReportForm.Show(CmdOpeningCreate.m_HWndRevit);
					Selection selection = this.m_cmdData.Application.ActiveUIDocument.Selection;
					for (;;)
					{
						try
						{
							List<Element> selElements = new List<Element>();
							RevitVersionFuncs.SetSelection(uiDoc.Selection, selElements);
							uiDoc.RefreshActiveView();
							selection.PickElementsByRectangle("");
							continue;
						}
						catch (Exception)
						{
							if (!openingCreateReportForm.m_bFormClose)
							{
								openingCreateReportForm.Close();
							}
							if (!openingCreateReportForm.m_bIsCreateOpening)
							{
								transactionGroup.RollBack();
								return false;
							}
							transactionGroup.RollBack();
							LinkedList<DbOpeningBase> needCrate3DOpeningData = openingCreateReportForm.GetNeedCrate3DOpeningData();
							if (!this.Create3DOpening(needCrate3DOpeningData))
							{
								YJKMessageBox.Show("开洞过程中出现错误，命令结束！");
								return false;
							}
							this.m_OpeningImpExpManager.SetOpenOperatorState(true);
							this.m_OpeningImpExpManager.ExportOpening2Xml(this.m_LstDbOpeningBase);
							YJKMessageBox.Show("开洞成功");
						}
						break;
					}
					result = true;
				}
				catch (Exception ex)
				{
					YJKMessageBox.Show(ex.Message);
					result = false;
				}
			}
			return result;
		}

		private bool CreateOpeningPreviewInstances()
		{
            GraphicsStyle lineStyle = CommonInterface.GetLineStyle(this.m_doc, "HYGreenLineStyle", new Autodesk.Revit.DB.Color(0, byte.MaxValue, 0), 5);
			if (lineStyle == null)
			{
				return false;
			}
            GraphicsStyle lineStyle2 = CommonInterface.GetLineStyle(this.m_doc, "HYRedLineStyle", new Autodesk.Revit.DB.Color(byte.MaxValue, 0, 0), 5);
			if (lineStyle2 == null)
			{
				return false;
			}
			PreViewScene preViewScene = new PreViewScene(this.m_doc, lineStyle.Id, 0.32808398950131235);
			PreViewScene preViewScene2 = new PreViewScene(this.m_doc, lineStyle2.Id, 0.32808398950131235);
			if (lineStyle == null || preViewScene2 == null)
			{
				return false;
			}
			ProgressBarForm progressBarForm = new ProgressBarForm(this.m_lstNoWoringBldOpening.Count + this.m_lstNoWoringStruOpening.Count + this.m_lstWoringBldOpening.Count + this.m_lstWoringStruOpening.Count, ProgressBarStyle.Blocks, true);
			progressBarForm.Text = "正在创建预览...";
			progressBarForm.ShowInTaskbar = false;
			progressBarForm.Show(CmdOpeningCreate.m_HWndRevit);
			if (!CmdOpeningCreate.CreateOpeningPreviewInstanceFromLstOpening(this.m_lstNoWoringStruOpening, progressBarForm, preViewScene2))
			{
				progressBarForm.Dispose();
				return false;
			}
			if (!CmdOpeningCreate.CreateOpeningPreviewInstanceFromLstOpening(this.m_lstNoWoringBldOpening, progressBarForm, preViewScene2))
			{
				progressBarForm.Dispose();
				return false;
			}
			if (!CmdOpeningCreate.CreateOpeningPreviewInstanceFromLstOpening(this.m_lstWoringStruOpening, progressBarForm, preViewScene))
			{
				progressBarForm.Dispose();
				return false;
			}
			if (!CmdOpeningCreate.CreateOpeningPreviewInstanceFromLstOpening(this.m_lstWoringBldOpening, progressBarForm, preViewScene))
			{
				progressBarForm.Dispose();
				return false;
			}
			progressBarForm.Dispose();
			return true;
		}

		private static bool CreateOpeningPreviewInstanceFromLstOpening(LinkedList<DbOpeningBase> lstOpening, ProgressBarForm progressBar, PreViewScene preViewScene)
		{
			try
			{
				foreach (DbOpeningBase dbOpeningBase in lstOpening)
				{
					Element element = null;
					dbOpeningBase.CreateOpeningPreviewInstance(out element, preViewScene);
					if (element != null)
					{
						dbOpeningBase.m_idModelGroup = element.Id;
					}
					progressBar.RefreshProgressBar();
					if (progressBar.m_stopTag)
					{
						return false;
					}
				}
			}
			catch (Exception ex)
			{
				YJKMessageBox.Show(ex.Message);
				return false;
			}
			return true;
		}

		private void GetCategoryOpeningLst()
		{
			WorksetTable worksetTable = this.m_doc.GetWorksetTable();
			WorksetId activeWorksetId = worksetTable.GetActiveWorksetId();
			Workset workset = worksetTable.GetWorkset(activeWorksetId);
			if (workset == null)
			{
				foreach (DbOpeningBase dbOpeningBase in this.m_LstDbOpeningBase)
				{
					Element element = this.m_doc.GetElement(dbOpeningBase.m_strHostUniqueId);
					if (dbOpeningBase.m_eOpeningState != EOpeningState.eOpen)
					{
						if (element != null)
						{
							if (dbOpeningBase.m_eHostObject == EHostObject.eArchWall)
							{
								this.m_lstWoringBldOpening.AddLast(dbOpeningBase);
							}
							else
							{
								this.m_lstWoringStruOpening.AddLast(dbOpeningBase);
							}
						}
						else if (dbOpeningBase.m_eHostObject == EHostObject.eArchWall)
						{
							this.m_lstNoWoringBldOpening.AddLast(dbOpeningBase);
						}
						else
						{
							this.m_lstNoWoringStruOpening.AddLast(dbOpeningBase);
						}
					}
				}
				return;
			}
			if (!workset.IsEditable)
			{
				YJKMessageBox.Show("当前工作集不可编辑！");
				return;
			}
			foreach (DbOpeningBase dbOpeningBase2 in this.m_LstDbOpeningBase)
			{
				Element element2 = this.m_doc.GetElement(dbOpeningBase2.m_strHostUniqueId);
				if (dbOpeningBase2.m_eOpeningState != EOpeningState.eOpen)
				{
					if (element2 != null && element2.WorksetId == activeWorksetId)
					{
						if (dbOpeningBase2.m_eHostObject == EHostObject.eArchWall)
						{
							this.m_lstWoringBldOpening.AddLast(dbOpeningBase2);
						}
						else
						{
							this.m_lstWoringStruOpening.AddLast(dbOpeningBase2);
						}
					}
					else if (dbOpeningBase2.m_eHostObject == EHostObject.eArchWall)
					{
						this.m_lstNoWoringBldOpening.AddLast(dbOpeningBase2);
					}
					else
					{
						this.m_lstNoWoringStruOpening.AddLast(dbOpeningBase2);
					}
				}
			}
		}

		public static WindowHandle m_HWndRevit;

		private Document m_doc;

		private DbOpeningImpExpManager m_OpeningImpExpManager;

		private LinkedList<DbOpeningBase> m_LstDbOpeningBase;

		private LinkedList<DbOpeningBase> m_lstNoWoringStruOpening = new LinkedList<DbOpeningBase>();

		private LinkedList<DbOpeningBase> m_lstNoWoringBldOpening = new LinkedList<DbOpeningBase>();

		private LinkedList<DbOpeningBase> m_lstWoringStruOpening = new LinkedList<DbOpeningBase>();

		private LinkedList<DbOpeningBase> m_lstWoringBldOpening = new LinkedList<DbOpeningBase>();

		private ExternalCommandData m_cmdData;
	}
}
